package org.loofer.uikit;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.Build.VERSION;
import android.support.v4.view.ViewCompat;
import android.util.AttributeSet;
import android.view.View;
import android.view.View.MeasureSpec;
import android.view.ViewGroup;
import android.view.ViewGroup.MarginLayoutParams;

public class CustomGridLayout extends ViewGroup {
    public static final int AUTO_FIT = -1;
    public static final int NO_STRETCH = 0;
    public static final int NO_STRETCH_NO_EXCEED = 4;
    public static final int SHOW_DIVIDER_BEGINNING = 1;
    public static final int SHOW_DIVIDER_END = 4;
    public static final int SHOW_DIVIDER_MIDDLE = 2;
    public static final int SHOW_DIVIDER_NONE = 0;
    public static final int STRETCH_COLUMN_WIDTH = 2;
    public static final int STRETCH_SPACING = 1;
    public static final int STRETCH_SPACING_UNIFORM = 3;
    private int mColumnWidth;
    private Drawable mDivider;
    private int mDividerColor;
    private int mDividerHeight;
    private Paint mDividerPaint;
    private int mDividerWidth;
    private boolean mFixLastRowDivider;
    private int mHorizontalSpacing;
    private int mNumColumns;
    private int mRequestedColumnWidth;
    private int mRequestedHorizontalSpacing;
    private int mRequestedNumColumns;
    private int mShowDividers;
    private int mStretchMode;
    private int mVerticalSpacing;

    public static class LayoutParams extends MarginLayoutParams {
        public LayoutParams(Context c, AttributeSet attrs) {
            super(c, attrs);
        }

        public LayoutParams(int width, int height) {
            super(width, height);
        }

        public LayoutParams(ViewGroup.LayoutParams source) {
            super(source);
        }

        public LayoutParams(MarginLayoutParams source) {
            super(source);
        }
    }

    public CustomGridLayout(Context context) {
        this(context, null);
    }

    public CustomGridLayout(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public CustomGridLayout(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        this.mNumColumns = -1;
        this.mStretchMode = 2;
        this.mHorizontalSpacing = 0;
        this.mVerticalSpacing = 0;
        this.mShowDividers = 0;
        this.mFixLastRowDivider = true;
        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CustomGridLayout, defStyle, 0);
        setHorizontalSpacing(a.getDimensionPixelOffset(R.styleable.CustomGridLayout_android_horizontalSpacing, 0));
        setVerticalSpacing(a.getDimensionPixelOffset(R.styleable.CustomGridLayout_android_verticalSpacing, 0));
        int index = a.getInt(R.styleable.CustomGridLayout_android_stretchMode, 2);
        if (index >= 0) {
            setStretchMode(index);
        }
        int columnWidth = a.getDimensionPixelOffset(R.styleable.CustomGridLayout_android_columnWidth, -1);
        if (columnWidth > 0) {
            setColumnWidth(columnWidth);
        }
        setNumColumns(a.getInt(R.styleable.CustomGridLayout_android_numColumns, 1));
        a.recycle();
    }

    public void setStretchMode(int stretchMode) {
        if (stretchMode != this.mStretchMode) {
            this.mStretchMode = stretchMode;
            requestLayoutIfNecessary();
        }
    }

    public int getStretchMode() {
        return this.mStretchMode;
    }

    public void setNumColumns(int numColumns) {
        if (numColumns != this.mRequestedNumColumns) {
            this.mRequestedNumColumns = numColumns;
            requestLayoutIfNecessary();
        }
    }

    public int getNumColumns() {
        return this.mNumColumns;
    }

    public int getRequestedNumColumns() {
        return this.mRequestedNumColumns;
    }

    public void setColumnWidth(int columnWidth) {
        if (columnWidth != this.mRequestedColumnWidth) {
            this.mRequestedColumnWidth = columnWidth;
            requestLayoutIfNecessary();
        }
    }

    public int getColumnWidth() {
        return this.mColumnWidth;
    }

    public void setHorizontalSpacing(int horizontalSpacing) {
        if (horizontalSpacing != this.mRequestedHorizontalSpacing) {
            this.mRequestedHorizontalSpacing = horizontalSpacing;
            requestLayoutIfNecessary();
        }
    }

    public int getHorizontalSpacing() {
        return this.mHorizontalSpacing;
    }

    public int getRequestedHorizontalSpacing() {
        return this.mRequestedHorizontalSpacing;
    }

    public void setVerticalSpacing(int verticalSpacing) {
        if (verticalSpacing != this.mVerticalSpacing) {
            this.mVerticalSpacing = verticalSpacing;
            requestLayoutIfNecessary();
        }
    }

    public int getVerticalSpacing() {
        return this.mVerticalSpacing;
    }

    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        int count = getChildCount();
        int parentLeft = getPaddingLeft();
        int parentTop = getPaddingTop();
        if (count > 0) {
            int columnCount = this.mNumColumns;
            int columnIndex = 0;
            int prevLeft = parentLeft;
            int prevTop = parentTop;
            int maxChildHeight = 0;
            for (int index = 0; index < count; index++) {
                View child = getChildAt(index);
                if (child.getVisibility() != 8) {
                    int width = child.getMeasuredWidth();
                    int height = child.getMeasuredHeight();
                    child.layout(prevLeft, prevTop, prevLeft + width, prevTop + height);
                    if (maxChildHeight < height) {
                        maxChildHeight = height;
                    }
                    prevLeft += this.mHorizontalSpacing + width;
                    columnIndex++;
                    if (columnIndex >= columnCount) {
                        columnIndex = 0;
                        prevLeft = parentLeft;
                        prevTop += this.mVerticalSpacing + maxChildHeight;
                    }
                }
            }
        }
    }

    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);
        if (widthMode == 0) {
            if (this.mColumnWidth > 0) {
                widthSize = (this.mColumnWidth + getPaddingLeft()) + getPaddingRight();
            } else {
                widthSize = getPaddingLeft() + getPaddingRight();
            }
            widthSize += getVerticalScrollbarWidth();
        }
        int availableChildWidth = (widthSize - getPaddingLeft()) - getPaddingRight();
        boolean didNotInitiallyFit = determineColumns(availableChildWidth);
        int childrenHeight = 0;
        int count = getChildCount();
        if (count > 0) {
            int columnCount = this.mNumColumns;
            int columnIndex = 0;
            int rowIndex = 0;
            int rowHeight = 0;
            int index = 0;
            while (index < count) {
                View child = getChildAt(index);
                if (child.getVisibility() != 8) {
                    LayoutParams p = (LayoutParams) child.getLayoutParams();
                    if (p == null) {
                        p = generateDefaultLayoutParams();
                        child.setLayoutParams(p);
                    }
                    int layoutWidth = p.width;
                    int layoutHeight = p.height;
                    if (this.mStretchMode == 4 && (((layoutWidth > this.mColumnWidth && count > 1) || layoutWidth > availableChildWidth) && layoutWidth > 0)) {
                        if (layoutHeight > 0) {
                            layoutHeight = (int) ((((float) this.mColumnWidth) / ((float) layoutWidth)) * ((float) layoutHeight));
                        }
                        layoutWidth = -1;
                    }
                    child.measure(getChildMeasureSpec(MeasureSpec.makeMeasureSpec(this.mColumnWidth, 1073741824), 0, layoutWidth), getChildMeasureSpec(MeasureSpec.makeMeasureSpec(0, 0), 0, layoutHeight));
                    int childHeight = child.getMeasuredHeight();
                    if (rowHeight < childHeight) {
                        rowHeight = childHeight;
                    }
                    columnIndex++;
                    if (columnIndex >= columnCount || index == count - 1) {
                        columnIndex = 0;
                        childrenHeight += rowHeight;
                        if (rowIndex > 0) {
                            childrenHeight += this.mVerticalSpacing;
                        }
                        rowIndex++;
                        rowHeight = 0;
                    }
                }
                index++;
            }
        }
        if (heightMode == 0) {
            heightSize = ((getPaddingTop() + getPaddingBottom()) + childrenHeight) + (getVerticalFadingEdgeLength() * 2);
        }
        if (heightMode == Integer.MIN_VALUE) {
            int ourSize = ((getPaddingTop() + getPaddingBottom()) + childrenHeight) + (getVerticalFadingEdgeLength() * 2);
            if (heightSize > ourSize) {
                heightSize = ourSize;
            }
        }
        if (widthMode == Integer.MIN_VALUE && this.mRequestedNumColumns != -1 && ((((this.mRequestedNumColumns * this.mColumnWidth) + ((this.mRequestedNumColumns - 1) * this.mHorizontalSpacing)) + getPaddingLeft()) + getPaddingRight() > widthSize || didNotInitiallyFit)) {
            widthSize |= ViewCompat.MEASURED_STATE_TOO_SMALL;
        }
        setMeasuredDimension(widthSize, heightSize);
    }

    protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
        return p instanceof LayoutParams;
    }

    protected LayoutParams generateDefaultLayoutParams() {
        return new LayoutParams(-1, -1);
    }

    public LayoutParams generateLayoutParams(AttributeSet attrs) {
        return new LayoutParams(getContext(), attrs);
    }

    protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
        return new LayoutParams(p);
    }

    final void requestLayoutIfNecessary() {
        if (getChildCount() > 0) {
            requestLayout();
            invalidate();
        }
    }

    private boolean determineColumns(int availableSpace) {
        int requestedHorizontalSpacing = this.mRequestedHorizontalSpacing;
        int stretchMode = this.mStretchMode;
        int requestedColumnWidth = this.mRequestedColumnWidth;
        boolean didNotInitiallyFit = false;
        if (this.mRequestedNumColumns != -1) {
            this.mNumColumns = this.mRequestedNumColumns;
        } else if (requestedColumnWidth > 0) {
            this.mNumColumns = (availableSpace + requestedHorizontalSpacing) / (requestedColumnWidth + requestedHorizontalSpacing);
        } else {
            this.mNumColumns = 2;
        }
        if (this.mNumColumns <= 0) {
            this.mNumColumns = 1;
        }
        switch (stretchMode) {
            case 0:
                this.mColumnWidth = requestedColumnWidth;
                this.mHorizontalSpacing = requestedHorizontalSpacing;
                break;
            case 4:
                int maxColumnWidth = (availableSpace - ((this.mNumColumns - 1) * requestedHorizontalSpacing)) / this.mNumColumns;
                if (requestedColumnWidth > maxColumnWidth) {
                    requestedColumnWidth = maxColumnWidth;
                }
                this.mColumnWidth = requestedColumnWidth;
                this.mHorizontalSpacing = requestedHorizontalSpacing;
                break;
            default:
                int spaceLeftOver = (availableSpace - (this.mNumColumns * requestedColumnWidth)) - ((this.mNumColumns - 1) * requestedHorizontalSpacing);
                if (spaceLeftOver < 0) {
                    didNotInitiallyFit = true;
                }
                switch (stretchMode) {
                    case 1:
                        this.mColumnWidth = requestedColumnWidth;
                        if (this.mNumColumns <= 1) {
                            this.mHorizontalSpacing = requestedHorizontalSpacing + spaceLeftOver;
                            break;
                        }
                        this.mHorizontalSpacing = (spaceLeftOver / (this.mNumColumns - 1)) + requestedHorizontalSpacing;
                        break;
                    case 2:
                        this.mColumnWidth = (spaceLeftOver / this.mNumColumns) + requestedColumnWidth;
                        this.mHorizontalSpacing = requestedHorizontalSpacing;
                        break;
                    case 3:
                        this.mColumnWidth = requestedColumnWidth;
                        if (this.mNumColumns <= 1) {
                            this.mHorizontalSpacing = requestedHorizontalSpacing + spaceLeftOver;
                            break;
                        }
                        this.mHorizontalSpacing = (spaceLeftOver / (this.mNumColumns + 1)) + requestedHorizontalSpacing;
                        break;
                }
                break;
        }
        return didNotInitiallyFit;
    }

    public void attachRecycleableView(View child) {
        ViewGroup.LayoutParams params = child.getLayoutParams();
        if (params == null) {
            params = generateDefaultLayoutParams();
            if (params == null) {
                throw new IllegalArgumentException("generateDefaultLayoutParams() cannot return null");
            }
        }
        attachRecycleableView(child, -1, params);
    }

    public void attachRecycleableView(View child, ViewGroup.LayoutParams params) {
        attachRecycleableView(child, -1, params);
    }

    public void attachRecycleableView(View child, int index, ViewGroup.LayoutParams params) {
        if (child != null) {
            child.onFinishTemporaryDetach();
            attachViewToParent(child, index, params);
            requestLayout();
        }
    }

    public void detachRecycleableView(View child) {
        if (child != null) {
            child.onStartTemporaryDetach();
            detachViewFromParent(child);
        }
    }

    private static int ceil(float value) {
        int newValue = (int) value;
        return value == ((float) newValue) ? newValue : newValue + 1;
    }

    public void setFixLastRowDivider(boolean fixLastRowDivider) {
        this.mFixLastRowDivider = fixLastRowDivider;
    }

    public void setShowDividers(int showDividers) {
        if (showDividers != this.mShowDividers) {
            requestLayout();
        }
        this.mShowDividers = showDividers;
    }

    public int getShowDividers() {
        return this.mShowDividers;
    }

    public void setDividerColor(int color) {
        float density = getResources().getDisplayMetrics().density;
        setDividerColor(color, ceil(1.0f * density), ceil(1.0f * density));
    }

    public void setDividerColor(int color, int dividerWidth, int dividerHeight) {
        if (this.mDividerColor != color) {
            this.mDividerColor = color;
            if (VERSION.SDK_INT >= 14) {
                this.mDivider = new ColorDrawable(this.mDividerColor);
            } else {
                this.mDividerPaint = new Paint();
                this.mDividerPaint.setColor(this.mDividerColor);
            }
            float density = getResources().getDisplayMetrics().density;
            this.mDividerWidth = Math.max(dividerWidth, ceil(1.0f * density));
            this.mDividerHeight = Math.max(dividerHeight, ceil(1.0f * density));
            setWillNotDraw(false);
            requestLayout();
        }
    }

    public int getDividerWidth() {
        return this.mDividerWidth;
    }

    protected void dispatchDraw(Canvas canvas) {
        super.dispatchDraw(canvas);
        drawDividerInner(canvas);
    }

    private void drawDividerInner(Canvas canvas) {
        if (this.mShowDividers == 0) {
            return;
        }
        if (this.mDivider != null || this.mDividerPaint != null) {
            int parentLeft = getPaddingLeft();
            int parentTop = getPaddingTop();
            int count = getChildCount();
            if (count > 0) {
                int columnCount = this.mNumColumns;
                int rowCount = ceil(((float) count) / ((float) columnCount));
                int prevLeft = parentLeft;
                int prevTop = parentTop;
                for (int row = 0; row < rowCount; row++) {
                    int maxChildHeight = 0;
                    for (int column = 0; column < columnCount; column++) {
                        int index = (row * columnCount) + column;
                        if (index >= count) {
                            break;
                        }
                        View child = getChildAt(index);
                        if (child.getVisibility() != 8) {
                            LayoutParams lp;
                            int width = child.getMeasuredWidth();
                            int height = child.getMeasuredHeight();
                            if (maxChildHeight < height) {
                                maxChildHeight = height;
                            }
                            if (hasRowDividerBeforeChildAt(row, column, rowCount)) {
                                lp = (LayoutParams) child.getLayoutParams();
                                drawHorizontalDividerInner(canvas, (child.getTop() - lp.topMargin) - this.mDividerHeight, prevLeft - lp.leftMargin, width);
                            }
                            if (hasColumnDividerBeforeChildAt(row, column)) {
                                lp = (LayoutParams) child.getLayoutParams();
                                drawVerticalDividerInner(canvas, prevTop - lp.topMargin, (child.getLeft() - lp.leftMargin) - this.mDividerWidth, height);
                            }
                            prevLeft += this.mHorizontalSpacing + width;
                        }
                    }
                    prevLeft = parentLeft;
                    prevTop += this.mVerticalSpacing + maxChildHeight;
                }
                fixLastRowDivider(canvas, rowCount);
            }
        }
    }

    private void fixLastRowDivider(Canvas canvas, int rowCount) {
        if (this.mFixLastRowDivider && rowCount > 1) {
            int columnCount = this.mNumColumns;
            int childCount = getChildCount();
            if (childCount % columnCount != 0) {
                int startColumn = childCount % columnCount;
                View lastChild = getChildAt(childCount - 1);
                int prevLeft = getPaddingLeft();
                int width = lastChild.getMeasuredWidth();
                prevLeft += (this.mHorizontalSpacing + width) * startColumn;
                LayoutParams lp = (LayoutParams) lastChild.getLayoutParams();
                int left = (prevLeft - lp.leftMargin) - this.mDividerWidth;
                drawVerticalDividerInner(canvas, lastChild.getTop() - lp.topMargin, left, lastChild.getMeasuredHeight());
                while (startColumn < columnCount) {
                    drawHorizontalDividerInner(canvas, (lastChild.getTop() - lp.topMargin) - this.mDividerHeight, prevLeft - lp.leftMargin, width);
                    prevLeft += this.mHorizontalSpacing + width;
                    startColumn++;
                }
            }
        }
    }

    private boolean hasColumnDividerBeforeChildAt(int rowIndex, int columnIdex) {
        if (columnIdex == 0) {
            if ((this.mShowDividers & 1) != 0) {
                return true;
            }
            return false;
        } else if (columnIdex == this.mNumColumns) {
            if ((this.mShowDividers & 4) == 0) {
                return false;
            }
            return true;
        } else if ((this.mShowDividers & 2) == 0) {
            return false;
        } else {
            return true;
        }
    }

    private boolean hasRowDividerBeforeChildAt(int rowIndex, int columnIdex, int rowCount) {
        if (rowIndex == 0) {
            if ((this.mShowDividers & 1) != 0) {
                return true;
            }
            return false;
        } else if (rowIndex == rowCount) {
            if ((this.mShowDividers & 4) == 0) {
                return false;
            }
            return true;
        } else if ((this.mShowDividers & 2) == 0) {
            return false;
        } else {
            return true;
        }
    }

    private void drawHorizontalDividerInner(Canvas canvas, int top, int left, int width) {
        if (VERSION.SDK_INT >= 14) {
            this.mDivider.setBounds(left, top, left + width, this.mDividerHeight + top);
            this.mDivider.draw(canvas);
            return;
        }
        canvas.drawRect((float) left, (float) top, (float) (left + width), (float) (this.mDividerHeight + top), this.mDividerPaint);
    }

    private void drawVerticalDividerInner(Canvas canvas, int top, int left, int height) {
        if (VERSION.SDK_INT >= 14) {
            this.mDivider.setBounds(left, top, this.mDividerWidth + left, top + height);
            this.mDivider.draw(canvas);
            return;
        }
        canvas.drawRect((float) left, (float) top, (float) (this.mDividerWidth + left), (float) (top + height), this.mDividerPaint);
    }
}
